package com.xijia.example.util;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.xijia.example.util.res.SiteCertCheckResult;
import com.xijia.example.util.res.SiteCheckResult;
import io.github.wslxm.springbootplus2.core.utils.date.XjLocalDateTimeUtil;

import javax.net.ssl.*;
import java.io.IOException;
import java.net.*;
import java.security.cert.X509Certificate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class SiteCheckUtil {

//    public static void main(String[] args) {
//        SiteCertCheckResult result = checkCertificateExpiry("https://chat.biotech-pack.com/main");
////        SiteCheckResult result = siteVisitCheck("https://chat.biotech-pack.com/main", null);
//
////        SiteCheckResult result = siteVisitCheck("https://file.mtoz-biolabs.com");
//        System.out.println(result.toString());
//
//
//    }


    /**
     * https 过期检查
     * @author 王松
     * @mail 1720696548@qq.com
     * @date 2024/9/25 13:59 
     */
    public static SiteCertCheckResult checkCertificateExpiry(String siteUrl) {
        SSLSocketFactory sslSocketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
        SSLSocket sslSocket = null;
        SiteCertCheckResult result = null;
        String newSiteUrl = siteUrl.replace("https://", "").replace("http://", "");
        if (newSiteUrl.contains("/")) {
            newSiteUrl = newSiteUrl.substring(0, newSiteUrl.indexOf("/"));
        }
        try {
            // 解析域名获取 IP 地址
            InetAddress inetAddress = InetAddress.getByName(newSiteUrl);
            String ipAddress = inetAddress.getHostAddress();
            //
            sslSocket = (SSLSocket) sslSocketFactory.createSocket(newSiteUrl, 443);
            // 设置读取数据的超时时间（毫秒）
            sslSocket.setSoTimeout(15 * 1000); // 例如设置为15秒

            X509Certificate cert = (X509Certificate) sslSocket.getSession().getPeerCertificates()[0];
            Date notBefore = cert.getNotBefore(); // 获取证书开始有效的时间
            Date notAfter = cert.getNotAfter();   // 获取证书过期的时间
            LocalDateTime startTime = XjLocalDateTimeUtil.parseLdt(notBefore);
            LocalDateTime endTime = XjLocalDateTimeUtil.parseLdt(notAfter);
            result = new SiteCertCheckResult(true, "ok", ipAddress, startTime, endTime);
        } catch (IOException e) {
            // throw new RuntimeException(e);
            result = new SiteCertCheckResult(false, "error: " + e.getMessage(), null, null, null);
        } finally {
            if (sslSocket != null) {
                try {
                    sslSocket.close();
                } catch (Exception e) {
                }
            }
        }
        return result;
    }

    /**
     *
     * 访问检查
     * jdk 1.8.0.131 有 bug， 一直错误 SSLHandshakeException: Received fatal alert: handshake_failure
     * 用jdk11/17 都正常, jdk8其他版本暂为测试
     * @param siteUrl
     * @param normalCodes 检查时标记为正常的状态, 如 403 / 404 部分平台返回 403/404 是正常访问
     * @date 2024/9/25 13:58
     * @return com.xijia.example.util.res.SiteCheckResult
     */
    public static SiteCheckResult siteVisitCheck(String siteUrl, List<String> normalCodes) {
        normalCodes = normalCodes != null ? normalCodes : new ArrayList<>();
        try {
            // 解析域名获取 IP 地址
            String newSiteUrl = siteUrl.replace("https://", "").replace("http://", "");
            if (newSiteUrl.contains("/")) {
                newSiteUrl = newSiteUrl.substring(0, newSiteUrl.indexOf("/"));
            }
            InetAddress inetAddress = InetAddress.getByName(newSiteUrl);
            String ipAddress = inetAddress.getHostAddress();
            // 发起请求检查访问
            HttpResponse response = HttpRequest.get(siteUrl)
                    .setFollowRedirects(true)
                    .timeout(15000) // 设置超时时间为 15 秒
                    .execute();
            int statusCode = response.getStatus();
            if (statusCode == 200) {
                return new SiteCheckResult(true, "ok", ipAddress, statusCode);
            } else if (statusCode == 403) {
                return new SiteCheckResult(normalCodes.contains(statusCode + ""), "403", ipAddress, statusCode);
            } else if (statusCode == 404) {
                return new SiteCheckResult(normalCodes.contains(statusCode + ""), "404", ipAddress, statusCode);
            } else if (statusCode == 500) {
                return new SiteCheckResult(normalCodes.contains(statusCode + ""), "500", ipAddress, statusCode);
            } else {
                return new SiteCheckResult(normalCodes.contains(statusCode + ""), statusCode + "", ipAddress, statusCode);
            }
        } catch (Exception e) {
            String msg = e.getMessage();
            if (msg.contains("timeout") || msg.contains("timed out")) {
                return new SiteCheckResult(false, "访问超时", null, 500);
            } else if ("Try again".equals(msg.trim())) {
                return new SiteCheckResult(false, "DNS临时解析失败", null, 500);
            } else if (msg.contains("refused")) {
                return new SiteCheckResult(false, "连接被拒绝", null, 500);
            } else {
                return new SiteCheckResult(false, "未知网络异常: " + msg, null, 500);
            }
        }
    }
}
